﻿namespace AnalyStock.DataManage;

internal interface IDownloadProgress
{
    CancellationToken Token { get; }
    bool IsBusy { get; }
    bool IsTokenCancel { get; }
    void Cancel();
    void Report(string taskNo, int progressPercentage, string userState);
}

public class DownloadProgress : IDownloadProgress, IDisposable
{
    private readonly CancellationTokenSource _tokenSource;
    private SendOrPostCallback _invokeHandlers;
    private MultitaskProgressEventArgs _multiTaskArgs;
    private SynchronizationContext _syncContext;

    public DownloadProgress()
    {
        _syncContext = SynchronizationContext.Current ?? new SynchronizationContext();
        _invokeHandlers = InvokeHandlers;
        _tokenSource = new CancellationTokenSource();
        IsBusy = false;
    }

    public void Dispose()
    {
        // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    public bool IsBusy { get; private set; }

    public bool IsTokenCancel => _tokenSource.IsCancellationRequested;

    public CancellationToken Token => _tokenSource.Token;

    public void Cancel()
    {
        _tokenSource?.Cancel();
    }

    void IDownloadProgress.Report(string taskNo, int progressPercentage, string userState)
    {
        IsBusy = progressPercentage < 100; //设置进程执行繁忙状态，防止意外操作 
        _multiTaskArgs.ChangeStateVal(taskNo, progressPercentage, userState);
        OnChangedEvent(ref _multiTaskArgs);
    }

    public event EventHandler<MultitaskProgressEventArgs> ProgressChanged;

    protected virtual void OnChangedEvent(ref MultitaskProgressEventArgs e)
    {
        // _syncContext.Post((e)=>ProgressChanged(this,e), e);
        _syncContext.Post(_invokeHandlers, e);
    }

    private void InvokeHandlers(object e)
    {
        ProgressChanged?.Invoke(this, (MultitaskProgressEventArgs)e);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            // TODO: 释放托管状态(托管对象)            
            ProgressChanged = null;
            _syncContext = null;
            _invokeHandlers = null;
            _tokenSource?.Dispose();
        }

        // TODO: 释放未托管的资源(未托管的对象)并重写终结器
        // TODO: 将大型字段设置为 null
    }
}

public struct MultitaskProgressEventArgs //: EventArgs
{
    public int ProgressPercentage { get; private set; }

    public string UserState { get; private set; }

    public string TaskNo { get; private set; }

    public void ChangeStateVal(in string taskNo, in int progPercentage, in string userState)
    {
        TaskNo = taskNo;
        ProgressPercentage = progPercentage;
        UserState = userState;
    }
}